package net.ib.mtalk.util;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;

import net.ib.mtalk.R;
import net.ib.mtalk.constant.MTalkConstant;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.drawable.Drawable;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;

public class GraphicUtil extends BaseGraphicUtil {
	
	public static final String MY_PROFILE_NAME = "myprofile.png_";
	public static final String DELETE_MY_PROFILE = "myprofile";
	public static final String PATH_PHOTO = "DCIM//Camera//";
	public static final String PATH_PROFILE = "mnTalk/profile";
	public static final String PATH_TALKBOX = "mnTalk/talkbox";
	
	/**
	 * USAGE : String.format(PROFILE_SMALL, sid); // 111.png_
	 */
	public static final String PROFILE_SMALL = "%s.png_";
	
	/**
	 * USAGE : String.format(PROFILE_BIG, sid); // 111_999.png_
	 */
	public static final String PROFILE_BIG = "%s_999.png_";
	
	/**
	 * Max Image Size
	 */
	public static final int IMAGE_SIZE_WARNING = 50;
	public static final int IMAGE_SIZE_PROFILE = 100;
	public static final int IMAGE_SIZE_BUDDY_PROFILE = 58;
	public static final int IMAGE_THUMB_SIZE	= 100;
	public static final int IMAGE_MAX_SIZE = 900;
	public static final int IMAGE_SAMPLING_SQUARE = 8;
	
	/**
	 * 자신Profile 가져오기
	 * @param fileurl
	 * @return
	 */
	public static boolean profileImageWriter(String fileurl) {
		File root = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), PATH_PROFILE);
		
		if(writeFileFromUrl(fileurl, root, MY_PROFILE_NAME) != null) return true;
		else return false;
	}
	
	public static boolean saveProfileImage(Bitmap profilePhoto) {
		Object result = saveProfileImageToBao(profilePhoto);
		return (result!=null);
	}
	
	/**
	 * 이미지 BITMAP을 PNG로 COMPRESS 한 byteArrayOutputStream 내보냄
	 * @param bitmap
	 * @return
	 */
	public static ByteArrayOutputStream bitmapToByteStream(Bitmap bitmap){
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bitmap.compress(CompressFormat.PNG, 100, baos);
		return baos;
	}
	
	/**
	 * 
	 * @param boas
	 * @param path
	 * @param fileName
	 * @throws IOException
	 */
	public static void saveByteArrayOutputStreamToFile(ByteArrayOutputStream boas, String path, String fileName) 
	throws IOException{
		FileOutputStream fos = null;
		try{
			File photoDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), path);
			if (!photoDirectory.canRead()) photoDirectory.mkdir();
			File photoFile = new File(photoDirectory, fileName);
			fos = new FileOutputStream(photoFile);
			fos.write(boas.toByteArray());
		} catch(Exception e) {
			MTalkLogWriter.e(e);
		} finally {
			if(fos!=null) fos.close(); 
		}// End Of Try-Catch-Finally
	}
	
	public static ByteArrayOutputStream saveProfileImageToBao(Bitmap profilePhoto){
		try {
			ByteArrayOutputStream baos = bitmapToByteStream(profilePhoto);
			
			File photoDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), PATH_PROFILE);
			if (!photoDirectory.canRead()) photoDirectory.mkdir();
			File photoFile = new File(photoDirectory, MY_PROFILE_NAME);
			FileOutputStream fos = new FileOutputStream(photoFile);
			fos.write(baos.toByteArray());
			return baos;
		} catch(Exception e) {
			MTalkLogWriter.e(e);
			return null;
		}
	}
	
	public static void writeBitmap(Bitmap bitmap, String path, String fileName, int page) {
		File scribbleDirectory = new File(path);
		if (!scribbleDirectory.canRead())
			scribbleDirectory.mkdir();

		File f = new File(fileName);

		FileOutputStream out = null;

		try {
			out = new FileOutputStream(f);
			bitmap.compress(CompressFormat.JPEG, 90, out);

		} catch (Exception e) {
		} finally {
			try {
				out.close();
			} catch (Exception e) {
			}
		}
	}
	
	public static String getCurruntTimeStr(){
		
		Calendar rightNow = Calendar.getInstance();// 날짜 불러오는 함수

		String timestr 
		 	 = new String ( rightNow.get(Calendar.YEAR) 
		 			+ String.format("%02d",rightNow.get(Calendar.MONTH)) 
		 			+ String.format("%02d",rightNow.get(Calendar.DATE))
		 			+ String.format("%02d",rightNow.get(Calendar.HOUR)) 
		 			+ String.format("%02d",rightNow.get(Calendar.MINUTE))
		 			+ String.format("%02d",rightNow.get(Calendar.SECOND)) );
		return timestr;
	}
	
	public static Uri attachFileWriter(String fileurl) {
		File root = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), PATH_PHOTO);
		return writeFileFromUrl(fileurl, root, fileurl.substring(fileurl.lastIndexOf("/")+1));
	}
	
	/**
	 * URL 에서 스트림을 받아서 absolutePath + "//" + fileName으로 파일 작성
	 * @param url
	 * @param absolutePath
	 * @param fileName
	 * @throws IOException 
	 */
	public static Uri writeFileFromUrl(String address, String absolutePath, String fileName) throws IOException{
		if (address == null) return null;
	
		File directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), absolutePath);
		return writeFileFromUrl(address, directory, fileName);
	}
	
	/**
	 * 
	 * @param fileurl
	 * @param dir
	 * @param localFileName
	 * @return fileUri
	 */
	public static Uri writeFileFromUrl(String fileurl, File dir, String localFileName) {
		Uri uri = null;
		try {
			URL url = new URL(fileurl);
			HttpURLConnection uc = (HttpURLConnection)url.openConnection();
			if(uc.getResponseCode() != HttpURLConnection.HTTP_OK )
			{
				uc = (HttpURLConnection) url.openConnection();
				uc.connect();
				
				if(uc.getResponseCode() != HttpURLConnection.HTTP_OK )
				{
					throw new IOException();
				}
			}
			InputStream is = uc.getInputStream();
			BufferedInputStream bs = new BufferedInputStream(is);
			
			if(!dir.canWrite())dir.mkdirs();
			if (dir.canWrite()) {
				File attachFile = new File(dir, localFileName);
				if(attachFile.exists()) {
					attachFile.delete();
					attachFile = new File(dir, localFileName);
				}
				FileOutputStream fos = new FileOutputStream (attachFile);
				
				int n = 0;
				while ((n = bs.read()) != -1) {
					fos.write(n);
				}
				fos.close();
				uri = Uri.fromFile(attachFile);
			}
			
		} catch (Exception e) {
			MTalkLogWriter.e(e);
		}
		return uri;
	}
	
	public static void writeFileFromBitmap(Bitmap bitmap, String path, String fileName, CompressFormat format, int quality) {
		
		if (bitmap == null)
			return;
		
		File directory = new File(path);
		if (!directory.exists())
			directory.mkdir();

		File f = new File(directory, fileName);
		
		MTalkLogWriter.i(f.toString());
		
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(f);
			bitmap.compress(format, quality, out);
			
		} catch (Exception e) {
			MTalkLogWriter.e(e);
		} finally {
			try {
				out.close();
			} catch (Exception e) {
			}
		}
	}
	
	public static Bitmap thumbnailFromUri(Context parentContext, Uri uri) {
		
		Bitmap preparedPhoto = null;
		
		InputStream photoStream = null;
		BitmapFactory.Options options = new BitmapFactory.Options();
		
		try {
			photoStream = parentContext.getContentResolver().openInputStream(uri);
			options.inSampleSize = IMAGE_SAMPLING_SQUARE;
			options.inDither = true;
			options.outHeight = IMAGE_THUMB_SIZE;
			options.outWidth = IMAGE_THUMB_SIZE;
			options.outMimeType = "mimeimage/jpeg";
			preparedPhoto = BitmapFactory.decodeStream(photoStream, null, options);
			
			if(preparedPhoto != null/* && getMajorAxis(preparedPhoto) > 150*/) {
				preparedPhoto = getResizedBitmap(preparedPhoto, IMAGE_THUMB_SIZE);
			}
		} catch (Exception e) {
			MTalkLogWriter.e(e);
			
			Drawable d = parentContext.getResources().getDrawable(R.drawable.alert_dialog_icon);
			preparedPhoto = Bitmap.createBitmap(IMAGE_SIZE_WARNING, IMAGE_SIZE_WARNING, Bitmap.Config.ARGB_8888);
			Canvas canvas = new Canvas(preparedPhoto);
			d.setBounds(0, 0, IMAGE_SIZE_WARNING, IMAGE_SIZE_WARNING);
			d.draw(canvas);
		} finally {
			try {
				if(photoStream!=null) 
					photoStream.close();
				photoStream = null;
			} catch (IOException e) {
				MTalkLogWriter.e(e);
			}
		}
		return preparedPhoto;
	}
	/**
	 * SD Card에 저장된 Image 를 가져온다. (Sid 를 넘기면 Uri 를 생성해 넘겨준다. )
	 * @param context
	 * @param sid
	 * @return
	 * @throws IOException
	 */
	/*public static Bitmap getProfile (Context context, Long sid) throws IOException {
		return ProfileFromUri(context, Uri.parse(HanlderMsgConst.PROFILE_PATH + sid + ".png_"));
	}*/
	
	
	/*public static void getBigProfile(Activity thisActivity, long sID, ImageView profileView) {
		String fileName = String.format(PROFILE_BIG, sID);
		String url = String.format(HanlderMsgConst.REQ_USER_PROFILE+"?SID=%s&Size=999&Round=Y", sID);
		ImageDownloader imageDownloader = ImageDownloader.getInstance();
		imageDownloader.download(url, profileView, Environment.getExternalStorageDirectory().getAbsolutePath()+"//"+PATH_PROFILE, fileName, CompressFormat.PNG);
	}*/
	
	/**
	 * Profile 을 다운로드 하고 해당 Image 를 ImgaeView 에 Set 해준다. 
	 * @param thisActivity
	 * @param sID
	 * @param profileView
	 */
	/*public static void getProfile(Activity thisActivity, long sID, ImageView profileView) {
		// 현재 HTTP로 가져옴
		String fileName = String.format(PROFILE_SMALL, sID);
		String url = String.format(HanlderMsgConst.REQ_USER_PROFILE+"?SID=%s&Size=50&Round=Y", sID);
		ImageDownloader imageDownloader = ImageDownloader.getInstance();
		imageDownloader.download(url, profileView, PATH_PROFILE, fileName, CompressFormat.PNG);
	}*/
	
	/**
	 * SD Card 에 저장된 Profile Image 를 가져온다. (Uri 를 통해서)
	 * @param parentContext
	 * @param uri
	 * @return
	 * @throws IOException
	 */
	public static Bitmap ProfileFromUri(Context parentContext, Uri uri) throws IOException {

		Bitmap preparedPhoto = null;
		
		InputStream photoStream = parentContext.getContentResolver().openInputStream(uri);
		
		preparedPhoto = BitmapFactory.decodeStream(photoStream);
		if(preparedPhoto == null) return null;
		
		return preparedPhoto;
	}
	
	
	
	public static Bitmap BitmapFromUri(Context parentContext, Uri uri, int maxLength) throws IOException {
		
		System.gc();
		
		Bitmap preparedPhoto = null;
		
		InputStream photoStream;
		BitmapFactory.Options options = new BitmapFactory.Options();
		
		int sampleSquare = IMAGE_SAMPLING_SQUARE;
		do {
			if (preparedPhoto != null && !preparedPhoto.isRecycled()) {
				preparedPhoto.recycle();
				System.gc();
			}
			
			if (sampleSquare == 0) maxLength = 0;
			
			photoStream = parentContext.getContentResolver().openInputStream(uri);
			options.inSampleSize = (int) Math.pow(2, sampleSquare);
			
			preparedPhoto = BitmapFactory.decodeStream(photoStream, null, options);
			
			if(preparedPhoto == null) return null;
			
			if(MTalkConstant.LOG_MODE) System.out.println("BitmapFromUri: " + sampleSquare + ", " + preparedPhoto.getHeight() + ", "	+ preparedPhoto.getWidth());
			
			int majorAxis = (preparedPhoto.getWidth() > preparedPhoto.getHeight())? preparedPhoto.getWidth() : preparedPhoto.getHeight();
			
			if(sampleSquare > 0) sampleSquare -= (int)(Math.log(maxLength / majorAxis) / Math.log(2));
			else sampleSquare = 0;
			
			if(maxLength <= 0) break;
		} while(preparedPhoto.getWidth() < maxLength / 2 && preparedPhoto.getHeight() < maxLength / 2);
		photoStream.close();
		
		System.gc();
		return preparedPhoto;
	}
	
	public static String UriFromData(Context parentContext, byte[] data, int maxLength) {
    	BitmapFactory.Options options = new BitmapFactory.Options();
		
    	Bitmap preparedPhoto = null;
    	
    	int sampleSquare = IMAGE_SAMPLING_SQUARE;
		do {
			if (preparedPhoto != null && !preparedPhoto.isRecycled()) {
				preparedPhoto.recycle();
				System.gc();
			}
			
			if (sampleSquare == 0) maxLength = 0;
			
			options.inSampleSize = (int) Math.pow(2, sampleSquare);
			
			preparedPhoto = BitmapFactory.decodeByteArray(data, 0, data.length, options);
			if(preparedPhoto == null) return null;
			
			if(MTalkConstant.LOG_MODE) System.out.println("BitmapFromUri: " + sampleSquare + ", " + preparedPhoto.getHeight() + ", "	+ preparedPhoto.getWidth());
			
			int majorAxis = (preparedPhoto.getWidth() > preparedPhoto.getHeight())? preparedPhoto.getWidth() : preparedPhoto.getHeight();
			
			if(sampleSquare > 0) sampleSquare -= (int)(Math.log(maxLength / majorAxis) / Math.log(2));
			else sampleSquare = 0;
			
			if(maxLength <= 0) break;
		} while(preparedPhoto.getWidth() < maxLength / 2 && preparedPhoto.getHeight() < maxLength / 2);
		
    	
		return MediaStore.Images.Media.insertImage(parentContext.getContentResolver(), preparedPhoto, "m&Talk", "");
    }
	
	/**
	 * 큰 사이즈의 프로필이미지
	 * @param parent
	 * @param cId
	 * @param sId
	 * @return
	 */
	/*public static Bitmap getBigContactPhoto(Context parent, String sId) {
		String fileName = String.format(PROFILE_BIG, sId);
		return getPhoto(parent, fileName);
	}*/
	
	/**
	 * 기본 사이즈의 프로필이미지  
	 * @param parent
	 * @param cId
	 * @param sId
	 * @return
	 */
	/*public static Bitmap getContactPhoto(Context parent, String sId) {
		String fileName = String.format(PROFILE_SMALL, sId);
		return getPhoto(parent, fileName);
	}*/
	
	/**
	 * SDCard 에 있는 Image 를 가져온다.
	 * @param parent
	 * @param fileName
	 * @return
	 */
	/*private static Bitmap getPhoto(Context parent, String fileName){
		Bitmap contactphoto = null;
		
		File photoDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), PATH_PROFILE);
		if (!photoDirectory.canRead()) photoDirectory.mkdir();
		File photoFile = new File(photoDirectory, fileName);
		
		if (photoFile.exists()) {
			try {
				contactphoto = GraphicUtil.ProfileFromUri(parent, Uri.parse(HanlderMsgConst.PROFILE_PATH + fileName));
			} catch (IOException e) {
	    		return null;
			}
		}

		return contactphoto;
	}*/
	
	/*public static Bitmap getTalkBoxImage(Context parent, String talkBoxCode, String fileName) {
		Bitmap talkboxImage = null;
		
		File photoDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "mnTalk//talkbox//"+talkBoxCode);
		if (!photoDirectory.canRead()) photoDirectory.mkdir();
		File photoFile = new File(photoDirectory, fileName + "_" + talkBoxCode + ".png_");
		
		if (photoFile.exists()) {
			try {
				talkboxImage = GraphicUtil.ProfileFromUri(parent, Uri.parse(HanlderMsgConst.TALKBOX_PATH + talkBoxCode + "/" + fileName + "_" + talkBoxCode + ".png_"));
			} catch (IOException e) {
				MTalkLogWriter.e(e);
			}
		}
		
		return talkboxImage;
	}*/	
	
	
	
	public static int getPixelFromDip(Context ctx, float dip) {
		float scale = ctx.getResources().getDisplayMetrics().density;
		return (int) (dip * scale + 0.5f);
	}
	
	/**
	 * 
	 * @param address
	 * @param sid
	 * @throws IOException
	 */
	public static void getProfileImage(String address, String sid) throws IOException {
		writeFileFromUrl(address, PATH_PROFILE, String.format(PROFILE_SMALL, sid));
	}

	/**
	 * 
	 * @param address - resource server url
	 * @param talkBoxCode
	 * @param fileName
	 */
	public static boolean getTalkboxImageByApi(String address, String directory, String talkBoxCode, String fileName) {
		try {
			// 토크박스 디렉토리 만들기
			File talkBox = new File (Environment.getExternalStorageDirectory().getAbsolutePath(), directory);
			if (!talkBox.canWrite()) talkBox.mkdirs();
			
			String d = talkBoxCode!="" ? directory+"//"+talkBoxCode : directory;
			File talkBoxDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), d);
			if(!talkBoxDirectory.canWrite())talkBoxDirectory.mkdirs();
			
			// 파일 가져옴
			writeFileFromUrl(address, talkBoxDirectory, fileName);
			return true;
		} catch (Exception e) {
			MTalkLogWriter.e(e);
			return false;
		}
	}
	
	
	/**
	 * SID의 모든 profile image를 지운다
	 * @param sid
	 */
	public static void deleteAllProfile(String sid){
		deleteProfileImage(sid);
		deleteLargeProfileImage(sid);
	}
	
	/**
	 * 작은 profile image 삭제
	 * @param sid
	 */
	public static void deleteProfileImage(String sid) {
		deleteSpecificFile(PATH_PROFILE, String.format(PROFILE_SMALL, sid));
	}
	
	/**
	 * 큰 profile image 삭제
	 * @param sid
	 */
	public static void deleteLargeProfileImage(String sid) {
		deleteSpecificFile(PATH_PROFILE, String.format(PROFILE_BIG, sid));
	}
	
	/**
	 * 특정 파일 삭제
	 * @param absolutePath - Android path
	 * @param fileName
	 */
	public static boolean deleteSpecificFile(String absolutePath, String fileName){
		File profileDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), absolutePath);
		if(!profileDirectory.canWrite()) return false;
		if (profileDirectory.canWrite()) {
			File attachFile = new File(profileDirectory, fileName);
			if (attachFile.exists()){
				MTalkLogWriter.d("SMSGraphicUtil:deleteSpecificFile:FilePath : " + attachFile.getAbsolutePath());
				attachFile.delete();
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 
	 * @param directory : mnTalk//talkbox
	 * @param filename : 111.png
	 * @return
	 */
	public static boolean isExistFile(String directory, String filename){
		String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "//" + directory + "//" + filename;
		File file = new File(filePath);
		if(file.length()>0){
			return true;
		} else {
			file.delete();
			return false;
		}
	}
	
	public static boolean checkProfileSaved(long sid) {
		File file =  new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "mnTalk//profile");
		if (file.exists()) {
			File profileFile = new File(file, Long.toString(sid)+".png_");
			if (profileFile.exists()) {
				return true;
			}
		}
		return false;	
	}
	
	public static boolean isImageMimeType(String s){
		if(s.equals("image/jpeg")) return true;
		else if(s.equals("image/jpg")) return true;
		else return false;
	}
	
	public static Bitmap getVideoFrame(String uri) {
		MediaMetadataRetriever retriever = new MediaMetadataRetriever();
		try {
			if (Build.VERSION.SDK_INT >= 10) {
				retriever.setDataSource(uri);
				return retriever.getFrameAtTime();
			} else {
				retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
				retriever.setDataSource(uri);
				return retriever.captureFrame();
			}
		} catch(Exception ex) {
			MTalkLogWriter.e(ex);
		} finally {
			try {
				retriever.release();
			} catch (RuntimeException ex) {
				MTalkLogWriter.e(ex);
			}
		}
		return null;
	} 

}
